/*
"JSFXGEN" - Arranger.as
Modular Integrated Development Environment for JesuSonic
Project page: http://jsfxgen.googlecode.com

Copyright 2009 Lubomir I. Ivanov

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package neolit123.jsfxgen
{
  // =========================================================
  // [ import
  // =========================================================
  import flash.display.Sprite;
  import flash.text.TextField;
  import flash.text.TextFieldType;
  import flash.text.TextFormat;
  import flash.text.TextFormatAlign;
  import flash.geom.Rectangle;
  import flash.utils.Timer;
  import flash.events.Event;
  import flash.events.MouseEvent;
  import flash.events.TimerEvent;
  import neolit123.ui.Box;
  import neolit123.ui.UIButton;
  import neolit123.ui.TextButton;
  // =========================================================
  // [ class
  // =========================================================
  public class Arranger extends Sprite
  {  
    // @ objects
    private var controls:Sprite;
    private var area:Sprite;
    private var mc:Sprite;
    private var bkg:Box;
    private var cbkg:Box;
    private var areabkg:Box;
    private var warea:Box;
    private var btn:UIButton;
    private var df:Function = Main.debug.df;
    private var changed:Boolean = false;
    private var desc_l:TextField;
    private var desc_txt:TextField;
    private var author_l:TextField;
    private var author_txt:TextField;
    private var width_l:TextField;
    private var width_txt:TextField;
    private var height_l:TextField;
    private var height_txt:TextField;
    private var saved_txt:TextField;
    private var stimer:Timer = new Timer(1000, 1);
    private var dragbtn:TextButton = new TextButton("+",0xffffff,0x000000,0xffffff);
    private var tgtmod:Object;
    // @ properties
    private const ch:Number = 80;
    private var tmpw:Number;
    private var tmph:Number;
    public var w:Number = 0;
    public var h:Number = 0;
    public var xyar:Array = [];
    public var desc:String = "";
    public var author:String = "";
    // @ text formats
    private var tf:TextFormat = new TextFormat("_sans", 12);
    // @ search strings
    // =========================================================
    // [ constructor
    // =========================================================
    public function Arranger():void
    {
      // @ set another dim for array
      // ------------------------
      // [ add bkg
      // ------------------------
      bkg = new Box(Main.sw,Main.sh,Main.bkgcolor,Main.bkgcolor);
      addChild(bkg);
      bkg.buttonMode = true;
      bkg.mouseChildren = false;
      bkg.useHandCursor = false;
      // -----------------------------
      // [ add work area and objects
      // -----------------------------
      area = new Sprite();
      mc = new Sprite();
      areabkg = new Box(Main.sw,Main.sh-ch,0xeeeeee,0xffffff);
      warea = new Box(400,300,0xffffff,0x0000ff);
      addChild(area);
      area.addChild(areabkg);
      area.addChild(warea);
      // ------------------------
      // [ set dragbtn
      // ------------------------ 
      dragbtn.x = warea.width;
      dragbtn.y = warea.height;
      // @ add tt
      Main.tt.add(dragbtn,"Set width/height"); 
      // @ do drag
      dragbtn.addEventListener(MouseEvent.MOUSE_DOWN, drag);
      function drag(e:MouseEvent = null):void
      {
        changed = true;
        var rect:Rectangle = new Rectangle(0,0,areabkg.width-15,areabkg.height-15);
        dragbtn.startDrag(false,rect);
        stage.addEventListener(MouseEvent.MOUSE_UP, stopdrag);
        stage.addEventListener(MouseEvent.MOUSE_MOVE, movedrag);
      }
      // @ move drag
      function movedrag(e:MouseEvent = null):void
      {
        warea.width = int(dragbtn.x);
        warea.height = int(dragbtn.y);
      } 
      // @ stop drag
      function stopdrag(e:MouseEvent = null):void
      {
        dragbtn.stopDrag();
        tmpw = warea.width; 
        tmph = warea.height;
        width_txt.text = tmpw.toString();
        height_txt.text = tmph.toString();
        stage.removeEventListener(MouseEvent.MOUSE_UP, stopdrag);
        stage.removeEventListener(MouseEvent.MOUSE_MOVE, movedrag);
      }
      // ------------------------
      // [ add contols container
      // ------------------------
      controls = new Sprite();
      cbkg = new Box(Main.sw,ch,0xcccccc,0x666666);
      cbkg.buttonMode = true;
      cbkg.mouseChildren = false;
      cbkg.useHandCursor = false;
      addChild(controls);
      controls.addChild(cbkg);
      controls.y = Main.sh-200;
      // ------------------------
      // [ add save / close
      // ------------------------
      btn = new UIButton();
      btn.setlabel("Save");
      btn.x = btn.y = 10;
      controls.addChild(btn);
      btn.addEventListener(MouseEvent.CLICK, save);
      btn = new UIButton();
      btn.setlabel("Close");
      btn.x = 10;
      btn.y = 45;
      controls.addChild(btn);
      btn.addEventListener(MouseEvent.CLICK, closef);
      function closef(e:MouseEvent = null):void
      {
        // @ if 'amodule' is moved
        if (changed)
        Main.dialog.update("Close arrangement? Settings will be lost!" , "Yes", "Cancel", doclose, Main.dialog.close);
        else 
        doclose();
      }
      // ------------------------
      // [ add text fields
      // ------------------------
      tf.leftMargin = 5;
      // @ add desc_l
      desc_l = new TextField;
      controls.addChild(desc_l);
      with (desc_l)
      {
        defaultTextFormat = tf;
        textColor = 0x000000;
        selectable = false;
        autoSize = "left";
        text = "Description:";
        x = 120;
        y = 10;
      }
       // @ add desc_txt
      desc_txt = new TextField;
      controls.addChild(desc_txt);
      with (desc_txt)
      {
        defaultTextFormat = tf;
        textColor = 0x000000;
        background = true;
        border = true;
        borderColor = 0;
        type = "input";
        desc = text = "";
        width = 200;
        height = 20;
        x = 120+desc_l.width+10;
        y = 10;
      }
      // @ add author_l;
      author_l = new TextField;
      controls.addChild(author_l);
      with (author_l)
      {
        defaultTextFormat = tf;
        textColor = 0x000000;
        selectable = false;
        autoSize = "left";
        text = "Author:";
        x = desc_l.x + (desc_l.width - width);
        y = 45;
      }
      // @ add author_txt;
      author_txt = new TextField;
      controls.addChild(author_txt);
      with (author_txt)
      {
        defaultTextFormat = tf;
        textColor = 0x000000;
        background = true;
        border = true;
        borderColor = 0;
        type = "input";
        author = text = "";
        width = 200;
        height = 20;
        x = 120+desc_l.width+10;
        y = 45;
      }
      // @ add width_l;
      width_l = new TextField;
      controls.addChild(width_l);
      with (width_l)
      {
        defaultTextFormat = tf;
        textColor = 0x000000;
        selectable = false;
        autoSize = "left";
        text = "Width:";
        x = author_txt.x + author_txt.width + 10;
        y = 10;
      }
      // @ add width_txt;
      width_txt = new TextField;
      controls.addChild(width_txt);
      with (width_txt)
      {
        defaultTextFormat = tf;
        textColor = 0x000000;
        background = true;
        border = true;
        borderColor = 0;
        type = "input";
        text = "400";
        width = 70;
        height = 20;
        restrict = "0-9";
        x = width_l.x + width_l.width + 10;
        y = 10;
      }
      // @ add height_l;
      height_l = new TextField;
      controls.addChild(height_l);
      with (height_l)
      {
        defaultTextFormat = tf;
        textColor = 0x000000;
        selectable = false;
        autoSize = "left";
        text = "Height:";
        x = width_l.x+(width_l.width - width);
        y = 45;
      }
      // @ add height_txt;
      height_txt = new TextField;
      controls.addChild(height_txt);
      with (height_txt)
      {
        defaultTextFormat = tf;
        textColor = 0x000000;
        background = true;
        border = true;
        borderColor = 0;
        type = "input";
        text = "300";
        width = 70;
        height = 20;
        restrict = "0-9";
        x = height_l.x +height_l.width + 10;
        y = 45;
      }
      // ------------------------
      // [ add update btn
      // ------------------------
      btn = new UIButton();
      btn.setlabel("Update");
      btn.setsize(70,null);
      btn.x = height_txt.x + height_txt.width + 20;
      btn.y = 25;
      controls.addChild(btn);
      btn.addEventListener(MouseEvent.CLICK, update);
      // ------------------------
      // [ add saved txt
      // ------------------------
      saved_txt = new TextField;
      controls.addChild(saved_txt);
      with (saved_txt)
      {
        defaultTextFormat = tf;  
        x = btn.x + btn.width + 10;
        y = btn.y + 5;
        text = "Saved";
        visible = false;
      }
      // ------------------------
      // [ hide on init
      // ------------------------
      visible = false;
    }
    // =========================================================
    // [ align editor to stage
    // =========================================================
    public function align(sw:Number,sh:Number):void
    {
      bkg.width = cbkg.width = areabkg.width = sw;
      bkg.height = sh;
      areabkg.height = controls.y = sh - ch;
    }
    // =========================================================
    // [ open editor for module
    // =========================================================
    public function open():void
    {
      df("ARR Open");
      // @ remove old drag and mc and add new
      mc = null;
      mc = new Sprite();
      area.addChild(mc);
      area.addChild(dragbtn);
      // @ hide bkg stuff for speed up?
      Main.mc.visible = Main.lines.visible = false;
      // @ set texts
      width_txt.text = w.toString();
      height_txt.text = h.toString();
      desc_txt.text = desc;
      author_txt.text = author;
      // @ go trought modules, get dimentions and add 'amods'
      var i:int;
      var m_ar:Array = Main.m_ar;
      var marlen:int = m_ar.length;
      var maxw:int = 0;
      var maxh:int = 0;
      for (i=0;i<marlen;i++)
      {
        if (m_ar[i] != undefined && m_ar[i].modw != 0 && m_ar[i].modh != 0)
        {
          // @ get max listed 'amod' width and height
          if (m_ar[i].modw > maxw) maxw = m_ar[i].modw;
          if (m_ar[i].modh > maxh) maxh = m_ar[i].modh;
          // @ crate 'amod' and add to container
          var amod:AModule = new AModule(m_ar[i].modid,m_ar[i].modw,m_ar[i].modh);
          amod.name = "amod"+i;
          mc.addChild(amod);
          // @ set x,y from array
          amod.x = xyar[i][0];
          amod.y = xyar[i][1];
          // @ roll over (set index)
          amod.addEventListener(MouseEvent.MOUSE_OVER, overmod, false, 0, true);
          function overmod(e:MouseEvent):void
          {
            e.target.parent.setChildIndex(e.target, e.target.parent.numChildren-1);  
          }
          // @ drag 'amod'
          amod.addEventListener(MouseEvent.MOUSE_DOWN, dragmod, false, 0, true);
          function dragmod(e:MouseEvent):void
          {
            tgtmod = e.target;
            tgtmod.alpha = 0.8;
            changed = true;
            var rect:Rectangle = new Rectangle(0,0,areabkg.width-e.target.width,areabkg.height-tgtmod.height);
            tgtmod.startDrag(false,rect);
            stage.addEventListener(MouseEvent.MOUSE_UP, stopdragmod);
          }
          // @ stop drag 'amod'
          function stopdragmod(e:MouseEvent):void
          {
            stage.removeEventListener(MouseEvent.MOUSE_UP, stopdragmod);
            tgtmod.stopDrag();
            tgtmod.alpha = 1;
            tgtmod.x = int(tgtmod.x);
            tgtmod.y = int(tgtmod.y);
          }        
          // @ add tooltip
          Main.tt.add(amod,"[ "+m_ar[i].modid+" ] "+m_ar[i].lb);
        }
      }
      // @ if w,h < maxw,maxh
      if (maxw>0) maxw = Math.max(maxw,425);
      if (maxw>w) width_txt.text = (maxw).toString();
      if (maxh>h) height_txt.text = (maxh).toString();
      // @ update h,w & begin
      update();
      visible = true;
      changed = false;
    }    
    // =========================================================
    // [ close window
    // =========================================================
    public function doclose():void
    {
      df("ARR Close");
      // @ remove old mc & dragbtn
      area.removeChild(mc);
      area.removeChild(dragbtn);
      // @ set visible and close
      visible = false;
      Main.mc.visible = Main.lines.visible = true;
      Main.dialog.close();
    }
    // =========================================================
    // [ update
    // =========================================================
    public function update(e:MouseEvent = null):void
    {      
      // @ update
      tmpw = Number(width_txt.text);
      tmph = Number(height_txt.text);
      dragbtn.x = tmpw;
      dragbtn.y = tmph; 
      // @ check if number is ok
      if (tmpw.toString() == "NaN" || tmpw < 0) tmpw = 0;width_txt.text = tmpw.toString();
      if (tmph.toString() == "NaN" || tmph < 0) tmph = 0;height_txt.text = tmph.toString();
      // @ update work area
      warea.width = tmpw;
      warea.height = tmph;
      df("ARR Updating GFX dimensions to [ "+width_txt.text+", "+height_txt.text+" ]");
    }
    // =========================================================
    // [ save
    // =========================================================
    private function save(e:MouseEvent=null):void
    {
      update();
      changed = false;
      w = Math.max(tmpw,425);
      h = tmph;
      desc = desc_txt.text;
      author = author_txt.text;
      // @ go trought modules and write x,y coordinates to 'xyar'
      var i:int;
      var m_ar:Array = Main.m_ar;
      var marlen:int = m_ar.length;
      for (i=0;i<marlen;i++)
      {
        if (m_ar[i] != undefined && m_ar[i].modw != 0 && m_ar[i].modh != 0)
        {
          xyar[i] = [];
          xyar[i] = [mc.getChildByName("amod"+i).x, mc.getChildByName("amod"+i).y];
        }
      }
      // @ show saved txt
      saved_txt.visible = true;
      stimer.start();
      stimer.addEventListener(TimerEvent.TIMER, hidesaved);
      df("ARR Settings saved");
    }
    // =========================================================
    // [ hide saved
    // =========================================================
    private function hidesaved(e:TimerEvent=null):void
    {
      saved_txt.visible = false;
    }    
  }
}
